﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Bejeweled.Support
{
    /// <summary>
    /// This is a game component that implements IUpdateable.
    /// </summary>
    public class Utils
    {

        public static bool checkDestroy(Diamond[,] Board, int height, int width, int x, int y, ref int point, bool count)
        {
            

            Random ran = new Random((int)DateTime.Now.Ticks);
            int n = 8;
            // int top, bot;
            // Board[x, y]
            int i = x;
            int j = y;
            int S1 = 1, S2 = 1;
            int Lowest = x-1;
            int[,] Temp = new int[10, 2];
            Temp[0, 0] = x;
            Temp[0, 1] = y;
            bool Same1 = true;
            bool Same2 = true;
            //
            // ROW
            //

            // left
            while (Same1 && j > 0)
            {
                if (Board[i, j - 1].id == Board[i, j].id)
                {
                    S1++;
                    j--;
                    Temp[S1 - 1, 0] = i;
                    Temp[S1 - 1, 1] = j;
                    if (j > Lowest)
                        Lowest = j;
                }
                else 
                    Same1 = false;
            }

            // reset value
            i = x;
            j = y;
            Same1 = true;

            // right
            while (Same1 && j < width-1)
            {
                if (Board[i, j + 1].id == Board[i, j].id)
                {
                    S1++;
                    j++;
                    Temp[S1 - 1, 0] = i;
                    Temp[S1 - 1, 1] = j;
                    if (j > Lowest)
                        Lowest = j;
                }
                else 
                    Same1 = false;
            }

            // checkdestroy
            if (S1 >= 3)
            {
                for (int k = Lowest; k >= 0; k--)
                {
                    if (k - S1 >= 0)
                        Board[Temp[S1 - 1, 0], k].id = Board[Temp[S1 - 1, 0], k - S1].id;
                    else
                    {
                        Board[Temp[S1 - 1, 0], k].id = ran.Next(1, n + 1);
                    }
                }

                if (count)
                    point += S1;

                for (int i2 = 0; i2 < height; i2++)
                {
                    for (int j2 = 0; j2 < width; j2++)
                    {
                        checkDestroy(Board, height, width, i2, j2, ref point, count);
                    }
                }
                return true;
            }

            // 
            // COLUM
            //

            // above
            while (Same2 && i > 0)
            {
                if (Board[i - 1, j].id == Board[i, j].id)
                {
                    S2++;
                    i--;
                    Temp[S2 - 1, 0] = i;
                    Temp[S2 - 1, 1] = j;
                    
                }
                else Same2 = false;
            }

            // reset value
            i = x;
            j = y;
            Same2 = true;

            // below
            while (Same2 && i < height-1)
            {
                if (Board[i + 1, j].id == Board[i, j].id)
                {
                    S2++;
                    i++;
                    Temp[S2 - 1, 0] = i;
                    Temp[S2 - 1, 1] = j;
                    
                }
                else Same2 = false;
            }

            // checkdestroy
            if (S2 >= 3)
            {
                for (int h = S2 - 1; h >= 0; h--)
                {
                    for (int k = Temp[h, 1]; k >= 0; k--)
                    {
                        if (k > 0)
                        {
                            Board[Temp[h, 0], k].id = Board[Temp[h, 0], k - 1].id;
                        }
                        else
                        {
                            Board[Temp[h, 0], k].id = ran.Next(1, n + 1);
                        }
                    }
                }

                // count score  
                if (count)
                    point += S2 +10;

                // checkdestroy all
                for (int i2 = 0; i2 < height; i2++)
                {
                    for (int j2 = 0; j2 < width; j2++)
                    {
                        checkDestroy(Board, height, width, i2, j2, ref point, count);
                    }
                }
                return true;
            }
            return false;
        }


        public static bool checkDestroy2Point(int x1, int y1, int x2, int y2, Diamond[,] Board, int height, int width)
        {
            Diamond[,] BoardCopy = new Diamond[10, 10];
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    BoardCopy[i, j] = new Diamond(Board[i, j].id, j, i);
                }
            }
            int temp = Board[x1, y1].id;
            Board[x1, y1].id = Board[x2, y2].id;
            Board[x2, y2].id = temp;
            int point = 0;
            if (checkDestroy(Board, height, width, x1, y1, ref point, true) == true || checkDestroy(Board, height, width, x2, y2, ref point, true) == true)
            {
                for (int i = 0; i < height; i++)
                {
                    for (int j = 0; j < width; j++)
                    {
                        Board[i, j].id = BoardCopy[i, j].id;
                    }
                }
                return true;
            }
            for (int i = 0; i < height; i++)
            {
                for (int j = 0; j < width; j++)
                {
                    Board[i, j].id = BoardCopy[i, j].id;
                }
            }
            return false;
        }

        public static bool checkGameOver(Diamond[,] Board, int height, int width)
        {
            // Xem mảng kim cương như một hình chữ nhật, lần lượt check 4 đỉnh và 4 cạnh của hình chữ nhật trước.
            int i, j;
            
            // check 4 đỉnh
            if (checkDestroy2Point(0, 0, 0, 1, Board, height, width) == true || checkDestroy2Point(0, 0, 1, 0, Board, height, width) == true
                || checkDestroy2Point(0, width - 1, 0, width - 2, Board, height, width) == true || checkDestroy2Point(0, width - 1, 1, width - 1, Board, height, width) == true
                || checkDestroy2Point(height - 1, 0, height - 1, 1, Board, height, width) == true || checkDestroy2Point(height - 1, 0, height - 2, 0, Board, height, width) == true
                || checkDestroy2Point(height - 1, width - 1, height - 1, width - 2, Board, height, width) == true || checkDestroy2Point(height - 1, width - 1, height - 2, width - 1, Board, height, width) == true
                )
                return false;
            // check 4 cạnh
            for (j = 1; j < width - 2; j++)
            {
                if (checkDestroy2Point(0, j, 0, j + 1, Board, height, width) == true
                    || checkDestroy2Point(0, j, 0, j - 1, Board, height, width) == true
                    || checkDestroy2Point(0, j, 1, j, Board, height, width) == true)
                    return false;
                if (checkDestroy2Point(height - 1, j, height - 1, j + 1, Board, height, width) == true
                    || checkDestroy2Point(height - 1, j, height - 1, j - 1, Board, height, width) == true
                    || checkDestroy2Point(height - 1, j, height - 2, j, Board, height, width) == true)
                    return false;
            }
            for (i = 1; i < height - 2; i++)
            {
                if (checkDestroy2Point(i, 0, i, 1, Board, height, width) == true
                    || checkDestroy2Point(i, 0, i - 1, 0, Board, height, width) == true
                    || checkDestroy2Point(i, 0, i + 1, 0, Board, height, width) == true)
                    return false;
                if (checkDestroy2Point(i, width - 1, i, width - 2, Board, height, width) == true
                    || checkDestroy2Point(i, width - 1, i - 1, width - 1, Board, height, width) == true
                    || checkDestroy2Point(i, width - 1, i + 1, width - 1, Board, height, width) == true)
                    return false;
            }
            // check từng viên còn lại
            for (i = 1; i < height - 2; i++)
                for (j = 1; j < width - 2; j++)
                {
                    if (checkDestroy2Point(i, j, i - 1, j, Board, height, width) == true
                        || checkDestroy2Point(i, j, i + 1, j, Board, height, width) == true
                        || checkDestroy2Point(i, j, i, j - 1, Board, height, width) == true
                        || checkDestroy2Point(i, j, i, j + 1, Board, height, width) == true)
                        return false;
                }
            return true;
        }


        
    }    
}
